package cn.good.yan.config.t2;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * 自定义 - 断言
 *
 * @author shengren.yan
 * @create 2024/3/19
 */
@Component
@Slf4j
public class CheckAuthRoutePredicateFactory extends AbstractRoutePredicateFactory<CheckAuthRoutePredicateFactory.Config> {

    public CheckAuthRoutePredicateFactory() {
        super(Config.class);

    }

    // // 将配置文件中的值按返回集合的顺序，赋值给配置类
    // @Override
    // public List<String> shortcutFieldOrder() {
    // return Arrays.asList(new String[]{"minAge", "maxAge"});
    // }

    // 将配置文件中的值按返回集合的顺序，赋值给配置类
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(new String[]{"minAge", "maxAge", "name"});
    }

    /**
     * 断言 （需要在yml配置更改配置）
     *      该返回方法，
     *          满足条件 是true  代表可以跳转成功，  false 代表失败，不会转发成功
     *       例子：
     *       访问 http://localhost:8080/one/aaa/test1 就跳转到 http://localhost:9310/aaa/test1该地址（临时重定向）
     *            成功原因：配置文件，配置：  - CheckAuth=30,11,yan ，如果 - CheckAuth=30,11,xxx  这样不会成功
     *       访问 http://localhost:8080/one/aaa/test1?age=16 就跳转到 http://localhost:9310/aaa/test1该地址（临时重定向）
     *           成功原因：age值大于  config.maxAge 值，就会成功，否则失败
     *
     * @param config
     * @return {@link Predicate}<{@link ServerWebExchange}>
     */
    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return (GatewayPredicate) exchange -> {
            log.info("调用了 - 自定义断言");
            // 获取参数是age的参数。
            String age = exchange.getRequest().getQueryParams().getFirst("age");
            if (StringUtils.isEmpty(age)) {
                return false;
            }
            Integer i = Integer.valueOf(age);
            System.out.println(config.maxAge);
            if (i > config.maxAge) {
                return true;
            }

            // 断言：如果CheckAuth是yan，就会返回true，开启了该自定义 断言
            // predicates:
            // - Path=/one/**
            // - CheckAuth=22
            // # - CheckAuth=yan
            if (config.getName().equals("yan")) {
                return true;
            }
            return false;
        };
    }

    // 配置类，属性用于接收配置文件中的值
    @Data
    public static class Config {
        private int minAge;
        private int maxAge;
        @NotNull
        private String name;
    }

}
